/***************************************************************************
 
    This file is part of Count_and_Check
    Copyright (C) 2019 uncle-lu

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
***************************************************************************/
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "tools.h"
#include <QDebug>
#include <QIODevice>
#include <QFileDialog>
#include <QMessageBox>
#include <QTextStream>
#include <QDesktopServices>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    m_icon_c = QIcon(":/images/c.png");
    m_icon_check = QIcon(":/images/checker.png");
    m_icon_folder = QIcon(":/images/Folder.png");

    filters << "*.cpp" << "*.c" << "*.h" << "*.cxx" << "*.cc";
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_New_Folder_triggered()
{
    QString path = QFileDialog::getExistingDirectory(this, tr("打开文件夹"), tr("."), QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);

    if(path.isEmpty())
    {
        return ;
    }

    path = QDir::cleanPath(path);

    main_Dir = QDir(path);

    ui->Topic->setText(path);

    init_table();

    return ;
}

void MainWindow::on_Author_triggered()
{
    QString dlgTitle = "The Author";

    QString strInfo = "Author: uncle-lu\nBlog: uncle-lu.org\nEmail: uncle-lu@qq.com\nWelcome to communicate!:)";

    QMessageBox::about(this, dlgTitle, strInfo);

    return ;
}

void MainWindow::on_projects_doc_triggered()
{
    QString dlgTitle = "About Count_and_Check";

    QString strInfo = "<font size='5' color='#FF6600'>Count_and_Check</font><br>V1.1<br>"
                      "A gadget that counts your lines of code.<br><br>"
                      "Project git: <a href=\"https://gitee.com/uncle-lu/Count_and_Check\">Count_and_Check</a><br>"
                      "Base on <a href=\"https://www.gnu.org/licenses/\">GNU General Public License</a><br>"
                      "Copyright (C) 2019 uncle-lu";

    QMessageBox::about(this, dlgTitle, strInfo);
    return ;
}

void MainWindow::init_table()
{
    QFileInfoList line = main_Dir.entryInfoList(filters,QDir::Files | QDir::AllDirs | QDir::NoDotAndDotDot,QDir::DirsFirst | QDir::Name);
    int line_count = line.count();

    ui->Table->clearContents();

    ui->Table->setRowCount(line_count);
    for(int i=0;i < line_count;++i)
    {
        QString name = line[i].fileName();

        Map[name] = i;
        if(line[i].isDir())
        {
            QTableWidgetItem *newItem = new QTableWidgetItem(m_icon_folder,name,2001);
            ui->Table->setItem(i,0,newItem);
        }
        else
        {
            QTableWidgetItem *newItem = new QTableWidgetItem(m_icon_c,name,2001);
            ui->Table->setItem(i,0,newItem);
        }
    }

    ui->Table->setSortingEnabled(false);
    ui->Table->setEditTriggers(QAbstractItemView::NoEditTriggers);
    return ;
}

void MainWindow::on_pushButton_clicked()
{
    QFileInfoList line = main_Dir.entryInfoList(filters, QDir::Files | QDir::AllDirs | QDir::NoDotAndDotDot, QDir::DirsFirst | QDir::Name);

    bool BigFlag = ui->checkBox->checkState() == 2 ? true : false;
    //qDebug() << BigFlag;
    QString text;
    text = tr("Name\tCount");
    int line_count = line.count();
    int All = 0;

    for(int i=0;i < line_count; ++i)
    {
        int All_count = 0;
        QString path = line[i].canonicalFilePath();
        QString name = line[i].fileName();
        //qDebug() << "canonicalPath: "<<path;
        //Change StatuBar
        ui->statusBar->showMessage(tr("Counting %1 %2%").arg(name).arg((long)(i+1)/line_count*100));
        path = path + '/';

        if(line[i].isDir())
        {
            //Count each dir
            Dir_Count(QDir(path), All_count);
        }
        else
        {
            All_count = File_Count(QDir(path));
        }
        //Change Table
        QTableWidgetItem *item = ui->Table->takeItem(Map[name],1);
        delete &item;
        item = new QTableWidgetItem(tr("%1").arg(All_count));
        ui->Table->setItem(Map[name],1,item);
        text = text + "\n" + name + "\t" + tr("%1").arg(All_count);
        All += All_count;
    }

    ui->statusBar->showMessage(tr("Done! Total:%1").arg(All));
    if(BigFlag)
    {
        text = text + "\n\n" + "All lines:" + tr("%1").arg(All);

        text = text + "\n\n" + "Created by: Count_and_Check";
        Write_Count(text);
    }
    return ;
}

void MainWindow::Dir_Count(QDir path, int & count)
{
    QFileInfoList line = path.entryInfoList(QDir::Files | QDir::AllDirs | QDir::NoDotAndDotDot,QDir::Name);

    int line_count = line.count();
    //qDebug() << line_count;

    for(int i=0;i<line_count; ++i)
    {
        //qDebug() << line[i].canonicalFilePath();
        if(line[i].isDir())
        {
            Dir_Count(QDir(line[i].canonicalFilePath()),count);
            continue;
        }
        QString suffix = line[i].completeSuffix();
        if(suffix == "c" || suffix == "cpp" || suffix == "h" || suffix == "cxx")
        {
            int temp;
            temp =  File_Count(line[i].canonicalFilePath());
            //qDebug() << tr("count %1").arg(line[i].absoluteFilePath()) << temp;
            count += temp;
        }
    }

    return ;
}

int MainWindow::File_Count(QDir path)
{
    QString file_path = path.absolutePath();
    file_path = QDir::cleanPath(file_path);
    QFile fi(file_path,this);

    QFileInfo Inf(fi);

    if(!Inf.size())
    {
        return 0;
    }

    fi.open(QIODevice::ReadOnly|QIODevice::Text);

    QTextStream in(&fi);
    std::vector<char> context;
    char temp;
    while(!in.atEnd())
    {
        in >> temp;
        if(temp != ' ' && temp != '\t')context.push_back(temp);
    }
    in >> temp;

    fi.close();

    int ans = Count_Line(&context);

    return ans;
}

void MainWindow::Write_Count(QString text)
{
    QString file_path = main_Dir.canonicalPath() + '/' + tr("Count_Result.txt");
    file_path = QDir::cleanPath(file_path);

    //qDebug() << file_path;
    QFile fi(file_path,this);

    fi.open(QIODevice::WriteOnly | QIODevice::Text);

    QTextStream out(&fi);
    out << text;

    fi.close();

    return ;
}

void MainWindow::on_pushButton_2_clicked()
{
    if(main_Dir.cdUp() )
    {
        ui->Topic->setText(main_Dir.absolutePath());
        init_table();
        ui->statusBar->showMessage("Up Done!");
    }
    else
    {
        ui->statusBar->showMessage(tr("Already in the root directory!"));
    }
    return ;
}

void MainWindow::on_Table_cellDoubleClicked(int row, int column)
{
    if(column == 1)return ;
    //qDebug()<<tr("%1 %2").arg(row).arg(column);
    QTableWidgetItem *item =  ui->Table->item(row, column);

    QString path = main_Dir.absolutePath() + '/' + item->text();
    path = QDir::cleanPath(path);

    QFileInfo info(path);
    if(info.isDir())
        Change_Dir(QDir(path));
    else
        QDesktopServices::openUrl( QUrl::fromLocalFile(path) );

    return ;
}

void MainWindow::Change_Dir(QDir path)
{
    //qDebug()<<path.absolutePath();
    if( path.exists() )
    {
        main_Dir = QDir( path.canonicalPath() );
        ui->Topic->setText(path.canonicalPath());

        init_table();
        ui->statusBar->showMessage("Change Done!");
    }
    else
    {
        QMessageBox::warning(this, tr("Folder not Found!"), tr("Folder %1 is't Found!").arg(path.canonicalPath()));
    }
    return ;
}
